package com.milan.analysis.common.extend;

import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.client.ClientHttpRequest;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.client.RequestCallback;
import org.springframework.web.client.RestTemplate;

import java.io.IOException;
import java.util.Collections;
import java.util.Map;

/**
 * 访问 REST 服务的 RequestCallback
 */
public class RestRequestCallback implements RequestCallback {

    private RestTemplate restTemplate;
    private MediaType contentType;
    private MediaType accept;
    private Object requestObject;
    private Map<String,String> sendHeaders;

    public RestRequestCallback() {
    }

    public RestRequestCallback(RestTemplate restTemplate, MediaType contentType, MediaType accept, Object requestObject) {
        this.restTemplate = restTemplate;
        this.contentType = contentType;
        this.accept = accept;
        this.requestObject = requestObject;
    }

    public RestRequestCallback(RestTemplate restTemplate, Map<String,String> sendHeaders, MediaType contentType, MediaType accept, Object requestObject) {
        this.restTemplate = restTemplate;
        this.contentType = contentType;
        this.accept = accept;
        this.requestObject = requestObject;
        this.sendHeaders = sendHeaders;
    }



    public RestTemplate getRestTemplate() {
        return restTemplate;
    }

    public void setRestTemplate(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }

    public MediaType getContentType() {
        return contentType;
    }

    public void setContentType(MediaType contentType) {
        this.contentType = contentType;
    }

    public MediaType getAccept() {
        return accept;
    }

    public void setAccept(MediaType accept) {
        this.accept = accept;
    }

    public Object getRequestObject() {
        return requestObject;
    }

    public void setRequestObject(Object requestObject) {
        this.requestObject = requestObject;
    }

    public Map<String, String> getSendHeaders() {
        return sendHeaders;
    }

    public void setSendHeaders(Map<String, String> sendHeaders) {
        this.sendHeaders = sendHeaders;
    }

    @SuppressWarnings("unchecked")
    @Override
    public void doWithRequest(ClientHttpRequest request) throws IOException {
        HttpHeaders headers = request.getHeaders();
        headers.setContentType(contentType);
        headers.setAccept(Collections.singletonList(accept));
        if(this.getSendHeaders() != null){
            for (Map.Entry<String, String> entry : this.getSendHeaders().entrySet()) {
                headers.set(entry.getKey(), entry.getValue());
            }
        }

        for(HttpMessageConverter httpMessageConverter : restTemplate.getMessageConverters()) {
            if(httpMessageConverter.canWrite(requestObject.getClass(), contentType)) {
                httpMessageConverter.write(requestObject, contentType, request);
                break;
            }
        }
    }
}